package au.com.acpfg.misc.spectra;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.knime.core.data.DataCell;
import org.knime.core.data.DataType;
public abstract class AbstractSpectraCell extends DataCell implements SpectralDataInterface {
/**
* for serialisation
*/
private static final long serialVersionUID = 1034645173992398749L;
/**
* Convenience method
*/
public static final DataType TYPE = DataType.getType(AbstractSpectraCell.class);
protected boolean equalsDataCell(DataCell dc) {
return (this == dc);
}
public abstract int hashCode();
public String toString() {
// NB: default must be not to round, as this would cause serialized spectra on disk to be rounded
return asString(false);
}
public String asString() {
return getID() + "\n"+"Peaks: "+getNumPeaks()+"\nMS Level: "+getMSLevel();
}
public abstract String getID();
public abstract double[] getIntensity();
public abstract int getMSLevel();
public abstract double[] getMZ();
public abstract AbstractSpectraCell getMyValue();
public abstract int getNumPeaks();
protected double scanMostIntense(boolean return_mz) {
double[] mz = getMZ();
double[] i = getIntensity();
double ci = Double.NEGATIVE_INFINITY;
double ret= Double.NaN;
for (int j=0; j<mz.length; j++) {
if (i[j] > 0.0 && i[j] > ci) {
ci = i[j];
ret= return_mz ? mz[j] : ci;
}
}
return ret;
}
public double getMZMostIntense() {
return scanMostIntense(true);
}
public double getIntensityMostIntense() {
return scanMostIntense(false);
}
protected double scanLeastIntense(boolean return_mz) {
double[] mz = getMZ();
double[] i = getIntensity();
double ci = Double.POSITIVE_INFINITY;
double ret= Double.NaN;
for (int j=0; j<mz.length; j++) {
if (i[j] > 0.0 && i[j] < ci) {
ci = i[j];
ret= return_mz ? mz[j] : ci;
}
}
return ret;
}
public double getMZLeastIntense() {
return scanLeastIntense(true);
}
public double getIntensityLeastIntense() {
return scanLeastIntense(false);
}
/**
* This method must be overridden in subclasses to ensure the possible charge states for the
* precursor ion are listed. Although the format is free-form, it should be similar to the
* Mascot Generic Format (MGF) as described on www.matrixscience.com for ease of processing.
*
* @return the emtpy string is returned by this implementation as the baseclass does not know the possible charge states
*/
public String getCharge() {
return "";
}
/**
* Template method (which may be overriden if required) to calculate Z based on the state of
* the spectra. It may not be 100% accurate, depending on available spectra state, but it
* guarantees to returns a small integer >= 1
*
* @return
*/
public int getProbableZ() {
String charge = getCharge();
if (charge.indexOf("2+") >= 0)
return 2;
else if (charge.indexOf("3+") >= 0) {
return 3;
}
Pattern p = Pattern.compile("^\\s*(\\d+)\\+*\\s*$");
Matcher m = p.matcher(charge);
if (m.matches()) {
Integer ch = new Integer(m.group(1));
if (ch.intValue() >= 1 && ch.intValue() < 20) // believable charge state?
return ch.intValue();
// probably bogus charge state... so lie... and
return 1;
}
// else
return 1;
}
}